import { IHttpResponse, IParam } from '@/core/interface';
import { Http } from '@/http';
import { ControlVOBase } from '../control-vo';
import { CtrlServiceBase } from './ctrl-service-base';

/**
 * 报表部件服务
 *
 * @class ReportPanelService
 */
class ReportPanelService<T extends ControlVOBase> extends CtrlServiceBase<T> {
	/**
	 * 数据源配置
	 *
	 * @private
	 * @type {(IParam)}
	 * @memberof ReportPanelService
	 */
	private config: IParam = {};

	/**
	 * Creates an instance of ReportPanelService.
	 * @param {new (data: any) => T} controlVOType
	 * @param {string} entityCodeName
	 * @param {IParam} [opts]
	 * @memberof ReportPanelService
	 */
	constructor(
		controlVOType: new (data: any) => T,
		entityCodeName: string,
		opts?: IParam
	) {
		super(controlVOType, entityCodeName, opts);
		if (opts && opts.CONFIG) {
			this.config = opts.CONFIG;
		}
		if (opts && opts.DATASOURCE) {
			this.config['mode'] = opts.DATASOURCE;
		}
	}

	handleResponse(response: IHttpResponse, opts: any = {}) {
		if (!response.data) {
			return response;
		}
		let result = null;
		const handleResult = (isCreate = false) => {
			if (response.data instanceof Array) {
				result = [];
				response.data.forEach((item: any, index: number) => {
					result.push(this.newControlVO(item));
				});
			} else {
				result = this.newControlVO(response.data);
			}
			// response状态，头文件
			if (response.config) {
				if (response.config['x-page']) {
					Object.assign(response, { page: Number(response.config['x-page']) });
				}
				if (response.config['x-per-page']) {
					Object.assign(response, {
						size: Number(response.config['x-per-page']),
					});
				}
				if (response.config['x-total']) {
					Object.assign(response, {
						total: Number(response.config['x-total']),
					});
				}
			}
			response.data = result;
		};
		handleResult();
		return response;
	}

	/**
	 * 获取请求参数
	 *
	 * @private
	 * @param {IParam} [data={}]
	 * @param {IParam} [viewParams={}]
	 * @memberof ReportPanelService
	 */
	private handleRequestParams(data: IParam = {}, config: IParam = {}) {
		let searchParams: IParam = {};
		if (config && Object.keys(config).length > 0) {
			Object.keys(config).forEach((field: string) => {
				if (config[field] && data[config[field]]) {
					Object.assign(searchParams, { [field]: data[config[field]] });
				}
			});
		}
		return searchParams;
	}

	async search(
		action: string,
		context: IParam = {},
		data: IParam = {}
	): Promise<IHttpResponse> {
		let result: Promise<any> | null = null;
		try {
			if (this.config && this.config.mode === 'DST') {
				if (this.config.requestUrl) {
					// 处理搜索参数
					let searchParams = this.handleRequestParams(
						data.viewParams,
						this.config.searchParams
					);
					// 处理url（searchParams[key]存在则填充值，否则替换成空字符串）
					let url = this.config.requestUrl;
					const matchArray = url.match(/\$\{.*?\}/g);
					if (matchArray && matchArray.length > 0) {
						matchArray.forEach((key: string) => {
							const tempStr = key.substring(2, key.length - 1);
							if (searchParams[tempStr]) {
								url = url.replace(key, searchParams[tempStr]);
							} else if (data.viewParams[tempStr]) {
								url = url.replace(key, data.viewParams[tempStr]);
							} else {
								url = url.replace(`/${key}`, '');
							}
						});
					}
					result = await Http.getInstance()[
						App.getProjectSetting().appRequestMode
					](url, searchParams);
				}
			} else {
				const { data: Data, context: Context } = this.handleRequestData(
					context,
					data
				);
				await this.initEntityService();
				if (this.appEntityService) {
					result = this.appEntityService[action ? action : 'FetchDefault'](
						Context,
						Data
					);
					if (result) {
						const response = await result;
						this.handleResponse(response);
					}
				}
			}
		} catch (error) {}
		return result;
	}
}
export default ReportPanelService;
